package com.ceair.flight.refund.service.ota.impl;

import com.ceair.flight.refund.dto.appmoblie.RefundApplyDto;
import com.ceair.flight.refund.dto.appmoblie.RefundAttachmentDto;
import com.ceair.flight.refund.dto.appmoblie.RefundAuditDto;
import com.ceair.flight.refund.dto.appmoblie.RefundDetailReq;
import com.ceair.flight.refund.dto.appmoblie.RefundPayDto;
import com.ceair.flight.refund.dto.appmoblie.RefundSegDto;
import com.ceair.flight.refund.dto.appmoblie.RefundTktDto;
import com.ceair.flight.refund.dto.ota.RefundAttachment;
import com.ceair.flight.refund.dto.ota.RefundDetailDto;
import com.ceair.flight.refund.dto.ota.RefundDetailRes;
import com.ceair.flight.refund.dto.ota.RefundSeg;
import com.ceair.flight.refund.dto.ota.RefundTicket;
import com.ceair.flight.refund.location.dao.IFlightOrderDao;
import com.ceair.flight.refund.location.dao.IRefundDetailDao;
import com.ceair.flight.refund.location.model.FlightOrderDO;
import com.ceair.flight.refund.location.model.PaxDO;
import com.ceair.flight.refund.location.model.TicketDO;
import com.ceair.flight.refund.service.ota.IRefundDetailService;
import com.ceair.flight.refund.util.Constants;
import com.ceair.flight.refund.util.GsonUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service("refundDetailService")
@Path("/ota")
public class RefundDetailServiceImpl implements IRefundDetailService {
	private static final Logger LOG = LoggerFactory.getLogger(RefundDetailServiceImpl.class);
	@Autowired
	private IFlightOrderDao flightOrderDao;
	@Autowired
	private IRefundDetailDao refundDetailDao;

    @Override
    @POST
    @Path("/refundDetail")
    @Consumes({"application/json"})
	@Produces(MediaType.APPLICATION_JSON)
	public RefundDetailRes refundDetail(RefundDetailReq request) {
    	LOG.info("调用getRefundDetail入参 :" + GsonUtil.toJson(request));
		RefundDetailRes refundDetailRes = new RefundDetailRes();
		List<RefundDetailDto> refundDetailList = new ArrayList<>();

		try {
			List<FlightOrderDO> listByOrderNo = flightOrderDao.getFlightOrderListByOrderNo(request.getOrderNo());
//		FlightOrderDO flightOrderDO = listByOrderNo.get(0);
			Set<String> tktSet = new HashSet<>();
			for (FlightOrderDO flightOrderDO:listByOrderNo){
				Set<PaxDO> paxs = flightOrderDO.getPaxs();
				for (PaxDO paxDO : paxs) {
					Integer paxSt = paxDO.getModifySt();
					if (3 != paxSt){
						continue;
					}
					Set<TicketDO> tickets = paxDO.getTickets();
					for (TicketDO ticketDO : tickets) {
						String tktNo = ticketDO.getTktNo();
						LOG.info("退票详情票号tktNo :" + tktNo);
						tktSet.add(tktNo);
					}
				}
			}
			List<String> tktNos = new ArrayList<String>(tktSet);
			// 判空
			if (tktNos.size() == 0 || null == tktNos) {
				refundDetailRes.setResultMsg("该大订单号: " + request.getOrderNo() + "不存在退票票号");
				LOG.info("该大订单号: " + request.getOrderNo() + "不存在退票票号");
				return refundDetailRes;
			}
			// 根据机票查询退票审核申请记录ID : apply_id
			List<Long> applyIds = refundDetailDao.getRefundApplyIdByticketId(tktNos);
			for (long applyId : applyIds) {
				LOG.info("退票 applyId: " + applyId);
				// 根据apply_id查询退票详情
				RefundApplyDto refundApplyDto = refundDetailDao.getRefundApplyDto(applyId);
				//返回参数转换OTA
				RefundDetailDto refundDetailDto = new RefundDetailDto();
				refundDetailDto.setRefundType("AIR");
				refundDetailDto = getRefundDetailDto(refundDetailDto, refundApplyDto);
				refundDetailList.add(refundDetailDto);
			}
			refundDetailRes.setRefundDetailList(refundDetailList);
			refundDetailRes.setResultCode(Constants.SUCCESS_CODE);
			refundDetailRes.setResultMsg(Constants.SUCCESS_MSG);
		}catch (Exception e){
			LOG.error("查询退票详情异常: ",e);
			refundDetailRes.setResultCode(Constants.ERROR_CODE);
			refundDetailRes.setResultMsg(Constants.SERVER_ERROR_MSG);
			return refundDetailRes;
		}catch (Error ex){
			LOG.error("查询退票详情异常: ",ex);
			refundDetailRes.setResultCode(Constants.ERROR_CODE);
			refundDetailRes.setResultMsg(Constants.SERVER_ERROR_MSG);
			return refundDetailRes;
		}

		return refundDetailRes;
	}
    //OTA接口转换
	private RefundDetailDto getRefundDetailDto(RefundDetailDto refDetail, RefundApplyDto refApply) {

		refDetail.setOrderNo(refApply.getRefundTkt().getOrderNo());
		refDetail.setRefundId(refApply.getId());

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		refDetail.setApplyDate(sdf.format(refApply.getCreatDate()));
		refDetail.setApplyPerson(refApply.getClaimerName());
		/*
		 * 281：自愿退票 282：非自愿退票； 283：航班延误或取消（航空公司原因） 286：病退 287：另购客票
		 */
		String claimReason = refApply.getClaimReason();
		/*
		 * 退票原因: (10:由于自身原因无法成行, 同意扣除退票手续费退票, 11:个人原因:行程变更, 12:个人事由, 21:由于航空公司原因, 无法成行,
		 * 申请全额退票, 22:由于乘机人因病(身故), 无法成行, 申请全额退票, 23:重购相同客票且已使用, 申请全额退票
		 * 24:其它原因,25出票后二十四小时内退票,26韩国当天退票,50:风控审核失败, 51:用户拒绝支付)
		 */
		//TODO  @王珽 重新明确状态
		switch (claimReason) {
		case "10":
			refDetail.setApplyType(Long.parseLong("281"));
			break;
		case "11":
			refDetail.setApplyType(Long.parseLong("281"));
			break;
		case "12":
			refDetail.setApplyType(Long.parseLong("281"));
			break;
		case "21":
			refDetail.setApplyType(Long.parseLong("283"));
			break;
		case "22":
			refDetail.setApplyType(Long.parseLong("286"));
			break;
		case "23":
			refDetail.setApplyType(Long.parseLong("287"));
			break;
		case "24":
			refDetail.setApplyType(Long.parseLong("282"));
			break;
		case "25":
			refDetail.setApplyType(Long.parseLong("282"));
			break;
		case "26":
			refDetail.setApplyType(Long.parseLong("282"));
			break;
		case "50":
			refDetail.setApplyType(Long.parseLong("282"));
			break;
		case "51":
			refDetail.setApplyType(Long.parseLong("282"));
			break;
		default:
			break;
		}
		/*
		 * 审核 审核阶段(100:申请, 200:一审, 300:二审, 400:退款) 我们审核有四个阶段,不兼容OTA,现仅展示最新状态
		 */
		Set<RefundAuditDto> refundAudits = refApply.getRefundAudits();
		if (!CollectionUtils.isEmpty(refundAudits)){
			List<Integer> arrayList = new ArrayList<Integer>();
			for (RefundAuditDto refundAuditDto : refundAudits) {
				String auditPhase = refundAuditDto.getAuditPhase();
				Integer parseInt = Integer.parseInt(auditPhase);
				arrayList.add(parseInt);
			}
			Integer max = Collections.max(arrayList);
			// 由于OTA返回参数数据与本系统查询不一致,以审核阶段最大优先
			for (RefundAuditDto refundAuditDto : refundAudits) {
				String auditPhase = refundAuditDto.getAuditPhase();
				Integer parseInt = Integer.parseInt(auditPhase);
				if (parseInt.equals(max)) {
					refDetail.setAuditComment(refundAuditDto.getAuditDesc());
					refDetail.setAuditDate(sdf.format(refundAuditDto.getAuditDate()));
					refDetail.setAuditPersonName(refundAuditDto.getAuditorName());
					refDetail.setAuditRemark(refundAuditDto.getAuditDesc());
				}
			}
		}

		refDetail.setLatestSubmitDate(sdf.format(refApply.getCreatDate()));
		refDetail.setMobile(refApply.getClaimerPhone());
		refDetail.setReason(refApply.getClaimReason());
		// 退票支付
		Set<RefundPayDto> refundPays = refApply.getRefundPays();
		if (refundPays != null && !refundPays.isEmpty()) {
			RefundPayDto refundPayDto = refundPays.iterator().next();
			refDetail.setRefundDate(sdf.format(refundPayDto.getRefundSuccessDate()));
			refDetail.setRefundRemark(refundPayDto.getRemark());
		}
		// 退票状态(101:提交申请, 109:退票异常, 201:等待审核(等待一审), 2011:等待用户更新, 209:一审异常, 301:等待二审,
		// 3011:等待重新审核, 302:二审通过, 309:生成退票单号异常, 401:等待退款, 409:退款异常, 501:退款成功, 901:退票完成,
		// 909:已删除)
		/*
		 * OTA: 退票状态 审核拒绝:252; 等待审核:251; 等待退款:254; 等待重新审核:253; 完成退款:255;
		 */
		//TODO  @王珽 重新明确状态
		String status = refApply.getStatus();
		switch (status) {
		case "101":
			refDetail.setStatus(252);
			break;
		case "109":
			refDetail.setStatus(253);
			break;
		case "201":
			refDetail.setStatus(251);
			break;
		case "2011":
			refDetail.setStatus(251);
			break;
		case "209":
			refDetail.setStatus(253);
			break;
		case "301":
			refDetail.setStatus(251);
			break;
		case "3011":
			refDetail.setStatus(251);
			break;
		case "302":
			refDetail.setStatus(254);
			break;
		case "309":
			refDetail.setStatus(253);
			break;
		case "401":
			refDetail.setStatus(254);
			break;
		case "409":
			refDetail.setStatus(253);
			break;
		case "501":
			refDetail.setStatus(255);
			break;
		case "901":
			refDetail.setStatus(255);
			break;
		default:
			break;
		}

		// 退票申请关联的票信息
		RefundTktDto refundTkt = refApply.getRefundTkt();
		List<RefundTicket> refundTicketList = new ArrayList<>();
		RefundTicket refundTicket = new RefundTicket();
		refundTicket.setPaxName(refundTkt.getPaxName());
		refundTicket.setInter(("D".equals(refundTkt.getTicketType())) ? false : true);
		refundTicket.setPaxType(refundTkt.getPaxType());
		refundTicket.setTicketNo(refundTkt.getTicketNo());
		// 票相关的航段信息
		List<RefundSeg> refundSegList = new ArrayList<>();


		Set<RefundSegDto> refundSegs = refundTkt.getRefundSegs();
		for (RefundSegDto refundSegDto : refundSegs) {
			RefundSeg refundSeg = new RefundSeg();
			refundSeg.setFlightNo(refundSegDto.getFlightNo());
			refundSeg.setArrival(refundSegDto.getArriveAirport());
			refundSeg.setArrivalDate(sdf.format(refundSegDto.getArriveDate()));
			refundSeg.setCabin(refundSegDto.getCabin());
			refundSeg.setCarrier(refundSegDto.getRealFlightNo());
			// refundSeg.setCouponNumber(couponNumber);退还达人券数
			refundSeg.setDeparture(refundSegDto.getDepartAirport());
			refundSeg.setDepartureDate(sdf.format(refundSegDto.getDepartDate()));
			refundSeg.setEiComment(refundSegDto.getEiContent());// EI项描述
			refundSeg.setFareBasis(refundSegDto.getFareBaise());
			refundSeg.setPrice(refundSegDto.getSalePrice().doubleValue());
			// refundSeg.setIssueDate(refundSegDto.getis);出票时间
			refundSeg.setPayPoint(refundTkt.getTktPoints());// 支付的积分数额
			refundSeg.setRefundPoint(refundTkt.getRefundPoints());// 应退还的积分数额
			refundSeg.setRefundAmount(refundSegDto.getRefundAmount() == null? 0d:Double.parseDouble(refundSegDto.getRefundAmount().toString()));
			refundSeg.setRefundFee(refundSegDto.getRefundFee()== null? 0d:Double.parseDouble(refundSegDto.getRefundFee().toString()));
			// refundSeg.setRemark(remark);
			refundSeg.setStatus(refundSegDto.getStatus());
			refundSeg.setTicketNo(refundTkt.getTicketNo());
			refundSegList.add(refundSeg);
		}
		refundTicket.setRefundSegList(refundSegList);
		refundTicketList.add(refundTicket);
		//退票申请关联的票信息
		refDetail.setRefundTicketList(refundTicketList);
		// 总退款金额（退还给用户的金额）
		refDetail.setTotalRefundAmount(refApply.getRefundAmount().doubleValue());
		// 总退款金额（退还给用户的金额）
		refDetail.setTotalRefundFee(refApply.getRefundFee().doubleValue());
		
		//TODO 附件 @王珽
		List<RefundAttachment> attachments = new ArrayList<>();
		RefundAttachment refundAttachment = new RefundAttachment();
		Set<RefundAttachmentDto> refundAttachments = refApply.getRefundAttachments();
		for (RefundAttachmentDto refundAttachmentDto : refundAttachments) {
			refundAttachment.setId(refundAttachmentDto.getId());
			refundAttachment.setName(refundAttachmentDto.getContentDesc());
//			refundAttachment.setContent(refundAttachmentDto.getAttchments()); 附件路径 @王珽
			attachments.add(refundAttachment);
		}
		refDetail.setAttachments(attachments);
		return refDetail;
	}

}
